﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using SharpSoda.Common;

namespace SharpSoda.Remote
{
    public class HttpRemoteCaller : IRemoteCaller
    {
        private CommonRng m_Rng = new CommonRng();
        private Dictionary<string, HttpRemoteChannel> m_Channels = new Dictionary<string, HttpRemoteChannel>();

        public void Refresh(Dictionary<string, string> entries)
        {
            Dictionary<string, string> currentEntries = new Dictionary<string, string>();
            Dictionary<string, string> uselessEntries = new Dictionary<string, string>();
            Dictionary<string, string> updatedEntries = new Dictionary<string, string>();
            Dictionary<string, string> newEntries = new Dictionary<string, string>();

            foreach (var item in m_Channels) currentEntries.Add(item.Key, item.Value.GetUri());

            foreach (var item in entries)
            {
                if (!currentEntries.ContainsKey(item.Key)) newEntries.Add(item.Key, item.Value);
                else
                {
                    if (!currentEntries[item.Key].Equals(item.Value)) updatedEntries.Add(item.Key, item.Value);
                }
            }

            foreach (var item in currentEntries)
            {
                if (!entries.ContainsKey(item.Key)) uselessEntries.Add(item.Key, item.Value);
            }

            if (uselessEntries.Count > 0 || updatedEntries.Count > 0 || newEntries.Count > 0)
            {
                lock (m_Channels)
                {
                    if (uselessEntries.Count > 0)
                        foreach (var item in uselessEntries) m_Channels.Remove(item.Key);

                    if (newEntries.Count > 0)
                        foreach (var item in newEntries) m_Channels.Add(item.Key, new HttpRemoteChannel(item.Value));

                    if (updatedEntries.Count > 0)
                    {
                        foreach (var item in updatedEntries)
                        {
                            m_Channels.Remove(item.Key);
                            m_Channels.Add(item.Key, new HttpRemoteChannel(item.Value));
                        }
                    }
                }
            }
        }

        public IRemoteChannel GetChannel(string entryName = "")
        {
            IRemoteChannel channel = null;
            if (entryName != null && entryName.Length > 0)
            {
                lock (m_Channels)
                {
                    if (m_Channels.ContainsKey(entryName)) channel = m_Channels[entryName];
                }
            }
            else
            {
                lock (m_Channels)
                {
                    int num = m_Rng.Next(m_Channels.Count);
                    int idx = 0;

                    foreach (var item in m_Channels)
                    {
                        if (idx == num)
                        {
                            channel = item.Value;
                            break;
                        }
                        idx++;
                    }
                }
            }
            return channel;
        }

        public List<IRemoteChannel> GetChannels()
        {
            List<IRemoteChannel> channels = new List<IRemoteChannel>();
            lock (m_Channels)
            {
                foreach (var item in m_Channels)
                {
                    channels.Add(item.Value);
                }
            }
            return channels;
        }
    }
}
